<?php

declare(strict_types=1);

namespace DreamCat\ObjectValid\Utils;

use ReflectionClass;
use ReflectionClassConstant;
use ReflectionFunctionAbstract;
use ReflectionParameter;
use ReflectionProperty;

/**
 * -
 * @author vijay
 */
class AnnotationUtils
{
    /**
     * 获取反射注解的对象
     * @param ReflectionProperty|ReflectionClass|ReflectionParameter|ReflectionFunctionAbstract|ReflectionClassConstant $reflection
     *      反射
     * @param ?string $className 注解要求的类名
     * @return object[]
     */
    public static function getAttrObjs(
        ReflectionProperty|ReflectionClass|ReflectionParameter|ReflectionFunctionAbstract|ReflectionClassConstant $reflection,
        string $className = null
    ): array {
        $attrs = $reflection->getAttributes();
        $list = [];
        foreach ($attrs as $attr) {
            if (!class_exists($attr->getName())) {
                continue;
            }
            if ($className && !is_a($attr->getName(), $className, true)) {
                continue;
            }
            $list[] = $attr->newInstance();
        }
        return $list;
    }

    /**
     * -
     * @param ReflectionProperty|ReflectionClass|ReflectionParameter|ReflectionFunctionAbstract|ReflectionClassConstant $reflection
     *      反射
     * @param ?string $className 注解要求的类名
     * @psalm-param class-string<T> $className
     * @psalm-return ?T 注解对象
     * @template T
     */
    public static function getAttrObj(
        ReflectionProperty|ReflectionClass|ReflectionParameter|ReflectionFunctionAbstract|ReflectionClassConstant $reflection,
        string $className = null
    ): ?object {
        $attrs = $reflection->getAttributes();
        foreach ($attrs as $attr) {
            if (!class_exists($attr->getName())) {
                continue;
            }
            if ($className && !is_a($attr->getName(), $className, true)) {
                continue;
            }
            return $attr->newInstance();
        }
        return null;
    }
}

# end of file
